package com.baitai.system.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.baitai.common.constant.CacheConstants;
import com.baitai.common.core.domain.model.LoginUser;
import com.baitai.common.core.redis.RedisCache;
import com.baitai.common.utils.DateUtils;
import com.baitai.common.utils.SecurityUtils;
import com.baitai.common.utils.StringUtils;
import com.baitai.system.domain.UserPointsLog;
import com.baitai.system.domain.UserSignInRecords;
import com.baitai.system.mapper.UserSignInRecordsMapper;
import com.baitai.system.service.ISysUserService;
import com.baitai.system.service.IUserPointsLogService;
import com.baitai.system.service.IUserSignInRecordsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baitai.system.mapper.SignInRuleMapper;
import com.baitai.system.domain.SignInRule;
import com.baitai.system.service.ISignInRuleService;
import org.springframework.transaction.annotation.Transactional;

/**
 * signInRuleService业务层处理
 *
 * @author ruoyi
 * @date 2024-07-10
 */
@Service
public class SignInRuleServiceImpl implements ISignInRuleService {
    @Autowired
    private SignInRuleMapper signInRuleMapper;
    @Autowired
    private IUserSignInRecordsService signInRecordsService;
    @Autowired
    private UserSignInRecordsMapper userSignInRecordsMapper;
    @Autowired
    private IUserPointsLogService pointsLogService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService userService;

    /**
     * 查询signInRule
     *
     * @param id signInRule主键
     * @return signInRule
     */
    @Override
    public SignInRule selectSignInRuleById(Long id) {
        return signInRuleMapper.selectSignInRuleById(id);
    }

    /**
     * 查询signInRule列表
     *
     * @param signInRule signInRule
     * @return signInRule
     */
    @Override
    public List<SignInRule> selectSignInRuleList(SignInRule signInRule) {
        return signInRuleMapper.selectSignInRuleList(signInRule);
    }

    /**
     * 新增signInRule
     *
     * @param signInRule signInRule
     * @return 结果
     */
    @Override
    public int insertSignInRule(SignInRule signInRule) {
        signInRule.setCreateTime(DateUtils.getNowDate());
        return signInRuleMapper.insertSignInRule(signInRule);
    }

    /**
     * 修改signInRule
     *
     * @param signInRule signInRule
     * @return 结果
     */
    @Override
    public int updateSignInRule(SignInRule signInRule) {
        signInRule.setUpdateTime(DateUtils.getNowDate());
        return signInRuleMapper.updateSignInRule(signInRule);
    }

    /**
     * 批量删除signInRule
     *
     * @param ids 需要删除的signInRule主键
     * @return 结果
     */
    @Override
    public int deleteSignInRuleByIds(Long[] ids) {
        return signInRuleMapper.deleteSignInRuleByIds(ids);
    }

    /**
     * 删除signInRule信息
     *
     * @param id signInRule主键
     * @return 结果
     */
    @Override
    public int deleteSignInRuleById(Long id) {
        return signInRuleMapper.deleteSignInRuleById(id);
    }

    @Override
    public SignInRule querySignInfo() {
        return signInRuleMapper.querySignInfo();
    }

    @Transactional
    @Override
    public Integer querySignCount(Long userId, String isFinish) {
        List<UserPointsLog> userPointsLogs = pointsLogService.selectUserPointsLogList(userId, DateUtils.startOfDay(), DateUtils.endOfDay(), "2");
        if (userPointsLogs.size() > 1) {
            return -1;
        }
        Integer result = 0;
        if ("1".equals(isFinish)) {
            if (redisCache.hasKey(CacheConstants.SIGN_IN_KEY + userId)) {
                Map<String, Integer> taskCache = redisCache.getCacheMap(CacheConstants.SIGN_IN_KEY + userId);
                Integer maxNum = taskCache.get("maxNum");
                Integer currNum = taskCache.get("currNum");
                currNum += 1;
                taskCache.put("currNum", currNum);
                redisCache.setCacheMap(CacheConstants.SIGN_IN_KEY + userId, taskCache);

                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 获取当天的结束时间（即第二天的开始时间）
                LocalDateTime endOfDay = currentDate.atStartOfDay().plusDays(1);
                // 计算当前时间到当天结束时间的秒数差
                long secondsRemaining = LocalDateTime.now().until(endOfDay, ChronoUnit.SECONDS);
                redisCache.expire(CacheConstants.SIGN_IN_KEY + userId,secondsRemaining);

                result = maxNum - currNum;
                if (result == 0) {
                    redisCache.deleteObject(CacheConstants.SIGN_IN_KEY + userId);
                    SignInRule signInRule = signInRuleMapper.querySignInfo();
                    BigDecimal pointsChange = new BigDecimal(signInRule.getViewsSuccessPoints());
                    UserSignInRecords records = userSignInRecordsMapper.getNewSignInRecords(userId);
                    LoginUser loginUser = SecurityUtils.getLoginUser();
                    String isPrivate = "";
                    if (StringUtils.isNotEmpty(loginUser.getUser().getIsPrivate()) && "2".equals(loginUser.getUser().getIsPrivate())) {
                        isPrivate = "1";
                        records = userSignInRecordsMapper.getNewSignInRecordsPrivate(userId);
                    }
                    if (records != null) {
                        if (signInRule.getContinuousDays().equals(records.getContinuousDays())) {
                            signInRecordsService.signIn(userId, signInRule.getNumberOfViews(), "0", signInRule.getViewsSuccessPoints(), "0", isPrivate);
                        } else if (signInRule.getContinuousDays().equals(StringUtils.add(records.getContinuousDays(), "1"))) {
                            BigDecimal changePoints = new BigDecimal(signInRule.getAdditionalPoints());
                            pointsChange = pointsChange.add(changePoints);
                            signInRecordsService.signIn(userId, signInRule.getNumberOfViews(), StringUtils.add(records.getContinuousDays(), "1"), signInRule.getViewsSuccessPoints(), signInRule.getAdditionalPoints(), isPrivate);
                        } else {
                            signInRecordsService.signIn(userId, signInRule.getNumberOfViews(), StringUtils.add(records.getContinuousDays(), "1"), signInRule.getViewsSuccessPoints(), "0", isPrivate);
                        }
                    } else {
                        userService.addPrizeCount(userId);
                        signInRecordsService.signIn(userId, signInRule.getNumberOfViews(), "1", signInRule.getViewsSuccessPoints(), "0", isPrivate);
                    }
                    //积分变动
                    pointsLogService.gainPoints(userId, pointsChange.toString(), "2", "签到获得积分");
                }
            }
        } else {
            if (redisCache.hasKey(CacheConstants.SIGN_IN_KEY + userId)) {
                Map<String, Integer> taskCache = redisCache.getCacheMap(CacheConstants.SIGN_IN_KEY + userId);
                Integer maxNum = taskCache.get("maxNum");
                Integer currNum = taskCache.get("currNum");
                result = maxNum - currNum;
            } else {
                SignInRule signInRule = signInRuleMapper.querySignInfo();
                Map<String, Integer> taskCache = new HashMap<>();
                taskCache.put("maxNum", Integer.parseInt(signInRule.getNumberOfViews()));
                taskCache.put("currNum", 0);
                redisCache.setCacheMap(CacheConstants.SIGN_IN_KEY + userId, taskCache);

                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 获取当天的结束时间（即第二天的开始时间）
                LocalDateTime endOfDay = currentDate.atStartOfDay().plusDays(1);
                // 计算当前时间到当天结束时间的秒数差
                long secondsRemaining = LocalDateTime.now().until(endOfDay, ChronoUnit.SECONDS);
                redisCache.expire(CacheConstants.SIGN_IN_KEY + userId,secondsRemaining);
                result = Integer.parseInt(signInRule.getNumberOfViews());
            }
        }
        return result;
    }
}
